/**
 * @file axis_ctrl.h
 * @brief X/Z轴通用控制接口（与硬件无关）
 * 功能：双轴独立控制，支持脉冲速度、原点回归、位置管理
 */
#ifndef AXIS_CTRL_H
#define AXIS_CTRL_H

#include "sys_pub.h"
// 轴类型枚举
typedef enum {
    AXIS_X = 0,
    AXIS_Z,
    AXIS_MAX  // 轴数量边界
} axis_id;

// 轴运行状态枚举
typedef enum {
    AXIS_STATE_IDLE = 0,          // 空闲
    AXIS_STATE_MOVING,            // 移动中
    AXIS_STATE_STEP_MOVE,         // 单步移动中
    AXIS_STATE_HOMING_STEP1,      // 原点回归-检测原点
    AXIS_STATE_HOMING_STEP2,      // 原点回归-脱离原点
    AXIS_STATE_HOMING_STEP3,      // 原点回归-快速寻原
    AXIS_STATE_HOMING_STEP4,      // 原点回归-精确定位
    AXIS_STATE_HOMING_OK,         // 回归完成
    AXIS_STATE_HOMING_ERR,        // 回归失败
    AXIS_STATE_ERROR              // 错误状态
} axis_state;

// 硬件操作函数指针（解耦硬件）
typedef struct {
    // 设置脉冲引脚电平（0=低,1=高）
    void (*set_pulse)(uint8_t level);
    // 设置方向引脚电平（0=反方向,1=正方向）
    void (*set_dir)(uint8_t level);
    // 读取原点传感器状态（1=检测到原点,0=未检测到）
    uint8_t (*read_origin)(void);
} axis_hw_ops;

// 原点回归参数配置（不同轴可差异化设置）
typedef struct {
    uint32_t max_homing_steps;    // 最大回归步数（防卡死）
    uint32_t escape_steps;        // 脱离原点步数
    uint32_t fine_adjust_steps;   // 精调退步数
    uint32_t timeout_ms;          // 回归超时时间(ms)
} axis_homing_cfg;

// -------------------------- 接口声明 --------------------------
/**
 * @brief 初始化指定轴
 * @param id 轴ID（AXIS_X/AXIS_Z）
 * @param hw_ops 硬件操作函数指针
 * @param homing_cfg 原点回归参数
 * @param default_pulse_interval 默认脉冲间隔(ms)
 */
void axis_init(axis_id id, const axis_hw_ops* hw_ops, 
              const axis_homing_cfg* homing_cfg, uint32_t default_pulse_interval);

/**
 * @brief 设置脉冲速度（间隔）
 * @param id 轴ID
 * @param interval_ms 脉冲间隔(ms)，值越小速度越快
 */
void axis_set_pulse_interval(axis_id id, uint32_t interval_ms);

/**
 * @brief 启动原点回归
 * @param id 轴ID
 * @return true=启动成功，false=忙或错误
 */
bool axis_start_homing(axis_id id);

/**
 * @brief 移动到相对原点的目标位置
 * @param id 轴ID
 * @param target_pos 目标位置（脉冲数）
 * @return true=启动成功，false=忙或参数无效
 */
bool axis_move_to(axis_id id, int32_t target_pos);

/**
 * @brief 单步移动
 * @param id 轴ID
 * @param dir 方向（0=反方向,1=正方向）
 */
void axis_move_step(axis_id id, uint8_t dir);

/**
 * @brief 前进指定步数（正方向）
 * @param id 轴ID
 * @param steps 前进步数（脉冲数，必须>0）
 * @return true=启动成功，false=参数无效/轴正忙
 */
bool axis_forward_steps(axis_id id, uint32_t steps);

/**
 * @brief 后退指定步数（反方向）
 * @param id 轴ID
 * @param steps 后退步数（脉冲数，必须>0）
 * @return true=启动成功，false=参数无效/轴正忙
 */
bool axis_backward_steps(axis_id id, uint32_t steps);

/**
 * @brief 紧急停止
 * @param id 轴ID
 */
void axis_stop(axis_id id);

/**
 * @brief 获取当前状态
 * @param id 轴ID
 * @return 轴状态（axis_state）
 */
axis_state axis_get_state(axis_id id);
/**
 * @brief 判断 * 判断指定轴是否完成当前移动（包括定位、步进、原点回归）
 * @param id 轴ID
 * @return true=已完成（空闲或回归完成），false=正在移动中或错误
 */
bool axis_is_move_complete(axis_id id);

/**
 * @brief 判断指定轴是否处于原点位置（基于传感器状态）
 * @param id 轴ID
 * @return true=在原点（传感器检测到），false=不在原点
 */
bool axis_is_at_origin(axis_id id);
/**
 * @brief 获取当前位置
 * @param id 轴ID
 * @return 当前位置（脉冲数，相对原点）
 */
int32_t axis_get_current_pos(axis_id id);

/**
 * @brief 1ms中断回调（必须在定时器中断中调用）
 */
void axis_1ms_tick(void);

#endif // AXIS_CTRL_H